'''
Created on 2011-1-19

@author: siqi
'''
import os,string, ConfigParser, sys, ConfigBase,time

minVars = { "1a1":1, "1a2":6, "1a3":1, "1a4":1, "1c":1, "1a6-1024":1, 
           "1a6-2048":1, "1a6-256":1,  "1a5":1, "1a6":1,
           "2a6":50, "3a6":16, "2a6-2048":16, "2a7":170, "1a7":1, "1a7-1024":25, "1a7-2048":25,"1a7-5":1, "1a7-5-1024":1, "3a7":1, "1a13":0, "1a13-5":0, "1a13-6":0, "quick-1a14-5y":2, "quick-1a15-5y":2
           , "1a7-1024-op40000":100}
maxVars = { "1a1":16, "1a2":12, "1a3":4, "1a4":1, "1c":4, 
           "1a6-1024":16, "1a6-2048":16, "1a6-256":4, "1a5":17, "1a6":16,
           "2a6":100, "3a6":50, "2a6-2048":100, "2a7":200, "1a7":200, "1a7-5":30, "1a7-1024":40, "1a7-2048":40,"1a7-5-1024":32, "3a7":1, "1a13":17, "1a13-5":17,"1a13-6":17, "quick-1a14-5y":9, "quick-1a15-5y":9
           , "1a7-1024-op40000":100}


moreAICommands = ["Rondje", "Convoy", "PathZilla", "OtviAI", "choochoo", "\"Denver & Rio Grande\"", 
            "AdmiralAI", "PAXLink", "chopper", "streettraffic", "rocketAi", "wrightAI", "simpleAI", "mogulAI",
            "trains", "trans" ,"towncars"]

dic = {}
dicFix = {}
dicSpecialCommands = {}
dicExecCommands = {}
terrain_type = ["very flat", "flat", "hilly", "mountainous"]
quantity_sea_lakes = ["sea very low", "sea low", "sea medium", "sea high"]

def set(option1, option2, val):
    config = ConfigParser.ConfigParser()
    config.optionxform=str
    filename = ConfigBase.getFileName()
    config.read(filename)
    print option1, option2, val, filename
    ttdVersion = config.set(option1, option2, val)
    config.write(open(filename, "w"))
    
    time.sleep(1);
    
def setRandomAI(num):
#    set("difficulty", "max_no_competitors", num)
#    print "setRandomAI ", num
    game_start_scr_path = ConfigBase.getGameStartScrPath()
    file = open(game_start_scr_path, "w")
    for i in xrange(0, num/1):
        print >> file, "start_ai "
    file.close()
    
def setSpecificAI(aiIdentifier,num=10):
#    set("difficulty", "max_no_competitors", num)
    game_start_scr_path = ConfigBase.getGameStartScrPath()
    file = open(game_start_scr_path, "w")
    for i in range(0,num):
        print "start_ai", moreAICommands[aiIdentifier - 1]
        print >> file, "start_ai " + moreAICommands[aiIdentifier - 1]
    file.close()
"""
This is used to read conf/*.conf configuration file, for init exp
"""
def parseConfigureFile(expName):
        expName = ConfigBase.getNameWithReplayPrefix(expName)
        if expName in minVars.keys():
            return maxVars[expName] + 1
        else:
            print "--------------------------------------------"
            filename = os.path.join("..", "conf",expName+".conf")
            file = open(filename)
            lines = file.readlines();
            l = []
            for line in lines:
                if line.find("#") != 0 and len(line.strip())>0:
                    l.append(line)
            if expName != string.strip(l[0]):
                print "ERROR reading incorrect configuration file"
                return
            numOfFactor = string.atoi(l[1])
            factors = []
            fixFactors = []
            commands = []
            total = 1
            pos = 2
            for i in range(0, numOfFactor):
                tup = string.split(l[pos])
                
                numberOfTwinFactors = string.atoi(tup[0])
                #tup[1] and tup[2] is min and max values
                #tup[3] is step
#                numberOfOptions = string.atoi(tup[2]) - string.atoi(tup[1]) + 1
                minVal = string.atoi(tup[1]);
                maxVal = string.atoi(tup[2]);
                step = 1;
                if(len(tup)==4):
                    step = string.atoi(tup[3]);
                tup = (numberOfTwinFactors, minVal, maxVal, step);    
                vals = range(minVal, maxVal+1, step);
                numberOfOptions = len(vals);
                total = total * numberOfOptions
                f = []
                pos = pos + 1
                f.append(tup)
                for j in range(0, numberOfTwinFactors):
                    tup = string.split(l[pos])
                    f.append(tup)
                    pos = pos + 1
                factors.append(f)
                print f
    #            print lines[2+i]
            numOfFixFactors = string.atoi(l[pos])
            dic[expName] = factors
            pos = pos + 1
            for i in range(0, numOfFixFactors):
                tup = string.split(l[pos])
                fixFactors.append(tup)
                pos = pos + 1
            dicFix[expName] = fixFactors
            numOfSpecialCommands = string.atoi(l[pos])
            pos = pos + 1
            for i in range(0, numOfSpecialCommands):
                line = string.split(l[pos])
                print line
                commands.append(line[0])
                pos = pos + 1
            dicSpecialCommands[expName] = commands
            numOfCommands = string.atoi(l[pos])
            exeCommands = [] 
            pos = pos + 1
            for i in range(0, numOfCommands):
                exeCommands.append(l[pos])
                pos = pos + 1
            dicExecCommands[expName] = exeCommands 
            print "--------------------------------------------"
            return total;
        sys.stderr.write("error in parseConfigureFile");

def getMinVarOfExp(expName):
    expName = ConfigBase.getNameWithReplayPrefix(expName) 
    parseConfigureFile(expName)
    if expName in minVars.keys():
        return minVars[expName]
    else:
        if expName == "1a8" or expName == "1a12":
            return 0     
        return 1

def getFactors(expName, step = 1):
    if(expName == "1a7-1024-op40000"):
        return [100,104,108,112,116,120,124,128,132,136,140,144,148,152,156,160];
    expName = ConfigBase.getNameWithReplayPrefix(expName)
#    print expName.find("1a10")
    if expName.find("1a10") >=0:
        return [500,1000,1500,2000]
    if expName.find("1a11") >=0:
        return getFactors1a11()
#    minVal = getMinVarOfExp(expName);
    minVal = 1;
    maxVal = parseConfigureFile(expName);
    return range(minVal, maxVal + 1, 1);

def getFactors1a11():
    return range(1, 18)
#    return [2, 12]
"""
This is used to find AI's performance under different map structure
"""
def configOf1a11(whichAI, terrain_type = 1, quantity_sea_lakes = 2, numOfAI=1):
    set("difficulty", "terrain_type", terrain_type)
    set("difficulty", "quantity_sea_lakes", quantity_sea_lakes)
    setSpecificAI(whichAI, numOfAI)
    
def config1a11All(expName, whichAI):
    expName = ConfigBase.getNameWithReplayPrefix(expName)
    pos1= expName.find("_")
    if(pos1 < 0):
        print "The expName \"" + expName + "\" is not correct, correct examples are quick-1a11_0_1, quick-1a11_1_0; So the game instance is not started";
        sys.exit(1);
    pos2 = expName.find("_", pos1+1)
    terrian_type = expName[pos1+1:pos2]
    water = expName[pos2+1:]
    print whichAI, expName, terrian_type, water
    print "the ai required is %d"%whichAI
    configOf1a11(whichAI, terrian_type, water)
    return True

def config1a10(factor):
    set("vehicle", "max_roadveh", factor)
    set("vehicle", "max_trains", 0)
    set("vehicle", "max_aircraft", 0)
    set("vehicle", "max_ships", 0)
    set("game_creation", "map_x", 11)
    set("game_creation", "map_y", 11)
    set("difficulty", "initial_interest", 2)#2 is the minimal    
    set("difficulty", "vehicle_costs", 0)# 0 is the minimal
    set("difficulty", "construction_cost", 0)
    set("difficulty", "subsidy_multiplier", 3)
    set("economy", "initial_city_size", 10)
    set("economy", "town_growth_rate", 10)
    set("economy", "larger_towns", 1)
    set("ai", "ai_max_opcode_till_suspend", 400000)
    set("ai", "ai_disable_veh_aircraft", "true")
    set("ai", "ai_disable_veh_ship", "true")
    set("ai", "ai_disable_veh_train", "true")
    setSpecificAI(4, 1)
    
def getExecuteableCommands(expName, pos=0):
    binaryPath = ConfigBase.getBinaryDirectoryForRunPath();
    default = "cd " + binaryPath + "; nohup ./openttd -D&"
    if expName.find("quick")>=0:
        default = "cd " + binaryPath + "; nohup ./openttd -D -q&"
        return default
    expName = ConfigBase.getNameWithReplayPrefix(expName)
    if expName == "1a10" or expName == "1a11":
        return default
    try:
        parseConfigureFile(expName)
    except:
        pass
    p = dicExecCommands.get(expName)
    if p != None:
        return p[pos]
    else: 
        return default

def config(expName, factor):
    expName = ConfigBase.getNameWithReplayPrefix(expName)
    orignFactor = factor
    numberOfAIs = 16;
    if expName.find("1a10")>=0:
        config1a10(factor)
        return
    if expName.find("1a11")>=0:
        config1a11All(expName, factor)
        return 
    for name in maxVars.keys():
        if expName == name:
            print "return"
            return 
    if dic.get(expName) == None:
        parseConfigureFile(expName)
        if dic.get(expName) == None and expName in maxVars.keys():
            print "error not config exist"
            return
    
    factors = dic[expName]
    numberOfOptionss = []
    """
    Careful, factor should be substracted by 1
    """
    factor = factor -1; 
    for i in range(0, len(factors)):
        tup = factors[i]
#        print tup
        #tup[0][0] numberOfTwinFactor, tup[0][1] minVal, tup[0][2] maxVal, tup[0][3] step;
        minVal = tup[0][1]; maxVal = tup[0][2]; step = tup[0][3];
        v = len(range(minVal, maxVal+1, step));
#        print v
        numberOfOptionss.append(v)
#        print string.atoi(tup[3]) - string.atoi(tup[2])
    print "************************************"
    for i in range(0, len(factors)):
        pth = len(factors) -1 -i
        tup = factors[pth];
        minVal = tup[0][1]; maxVal = tup[0][2]; step = tup[0][3];
        vals = range(minVal, maxVal+1, step);
        val = vals[factor % numberOfOptionss[pth]]
#        val = factor % numberOfOptionss[pth] + string.atoi(factors[pth][0][1])
        numOfSameVal = factors[pth][0][0]
        for j in range(0, numOfSameVal):            
            set(factors[pth][j+1][0], factors[pth][j+1][1], val)
            if(factors[pth][j+1][1] == "max_no_competitors"):
                numberOfAIs = val;
        factor = factor // numberOfOptionss[pth]
        sys.stdout.write(factors[pth][j+1][0] +", " + factors[pth][j+1][1] + " %d"%val)
        print ""
    fixFactor = dicFix[expName]
    for i in range(0, len(fixFactor)):
        set(fixFactor[i][0], fixFactor[i][1], string.atoi(fixFactor[i][2]))
    commands = dicSpecialCommands[expName]
    for i in range(0, len(commands)):
        if (string.strip(commands[i]) == "setRandomAI"):
            print "start %d AIs"%numberOfAIs;
            setRandomAI(numberOfAIs)

if __name__ == "__main__":
#    i = getExecuteableCommands("1a7-1024")
#    setSpecificAI(3, 1)
#    factors = getFactors("1a12")
#    print factors 
#    for factor in getFactors("quick-1a11_0_0"):
#        config("quick-1a11_0_0", factor)
#    print getExecuteableCommands("quick-1a11_0_0")
    
#    config("quick-1a11");
    def filename():
        return "C:\\Users\\siqi\\Documents\\OpenTTD";
    expName = "quick-1a11"; #4a7
    ConfigBase.getBinaryDirectoryPath = filename
    factors = getFactors(expName)
    print factors
    for factor in getFactors(expName):
        config(expName, factor)

#    for factor in getFactors("1a7-1024-op40000"):
#        config("1a7-1024-op40000", factor)
#    print getExecuteableCommands("1a7-1024-op4000")
    
#    for factor in getFactors("1a12"):
#        print factor
#        config("1a12",factor)
##    print "val of i ", i
#    for i in range(1, 18):
#        config("1a11_0_0", i)
#    for i in range(1, 18):
#        config("1a11_0_1", i)
#    for i in range(1, 18):
#        config("1a11_1_2", i)
#    print parseConfigureFile("1a7-1024")